package edu.langnan.xiaoli.service.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import edu.langnan.xiaoli.constant.XiaoLiConstants;
import edu.langnan.xiaoli.core.domain.PictureDO;
import edu.langnan.xiaoli.exception.file.FileEmptyException;
import edu.langnan.xiaoli.service.FileUploadService;
import edu.langnan.xiaoli.service.PictureService;
import edu.langnan.xiaoli.utils.StringUtils;
import edu.langnan.xiaoli.utils.file.FileUploadUtils;
import edu.langnan.xiaoli.utils.file.MimeTypeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;

/**
 * @author cql
 */
@Service("aliyunFileUploadService")
public class AliyunFileUploadServiceImpl implements FileUploadService {


    @Value("${aliyun.oss.bucketName}")
    private String bucketName;

    @Value("${aliyun.oss.endpoint}")
    private String endpoint;

    @Value("${aliyun.oss.accessKeyId}")
    private String accessKeyId;

    @Value("${aliyun.oss.accessKeySecret}")
    private String accessKeySecret;

    @Value("${aliyun.oss.imgPath}")
    private String imgPath;

    @Autowired
    private PictureService pictureService;

    @Override
    public PictureDO uploadImg(MultipartFile images) {
        if (StringUtils.isNull(images)) {
            throw new FileEmptyException();
        }
        // 校验图片大小,格式,文件名
        FileUploadUtils.assertAllowed(images, MimeTypeUtils.IMAGE_EXTENSION);

        // 图片重命名
        String fileName = images.getOriginalFilename();

        // 图片路径
        String url = imgPath + "/" + fileName;

        // 上传图片至阿里云对象存储
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, url, new ByteArrayInputStream(images.getBytes()));

            // 上传图片
            ossClient.putObject(putObjectRequest);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        // 阿里云图片存路径
        String path = url;
        // 阿里云访问地址 - url
        url = XiaoLiConstants.ROOT_PATH + url;

        PictureDO picture = pictureService.insertPicture(path, url);

        return picture;
    }

    @Override
    public void deleteImage(PictureDO pictureDO) {

        pictureService.deleteImage(pictureDO);

        // 创建OSSClient实例
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            // 删除文件或目录。如果要删除目录，目录必须为空。
            ossClient.deleteObject(bucketName, pictureDO.getPath());
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

